using System;
using FireStarter.Base;
using FireStarter.Base.BusinessObjectMerger;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;

namespace FireStarterModeller.Logic
{
    public class DMSolutionMerger : BusinessObjectMerger
    {
        public DMSolutionMerger(IMergableBo toMergeableBO)
            : base(toMergeableBO, null)
        {
        }

        protected override bool MustIgnoreProperty(IBOProp prop)
        {
            if (base.MustIgnoreProperty(prop)) return true;
            return prop.PropertyName == "GenerateCode" || prop.PropertyName == "NeedsRegeneration";
        }

        protected override IMergableBo CreateMergedBusinessObject(ISingleRelationship toSingleRelationship, IMergableBo fromRelatedBO, IBusinessObject toBO)
        {
            //This is a strange relationship since the DMProperty is owned by the DMClass and the 
            // relationship has to find the exact DMProperty that the DMClass has so as to work.
            // Another approach which might be more elegant would be to set the PropName and related prop name and
            // not the actual property. We could then run the post load processer against this to sort the actual
            // property out. This would however require some fairly significant changes to the
            // BusinessObjectMerger so for now I am living with this Hack_
            if (toSingleRelationship.RelationshipName == "Property" && toBO.GetType().Name == "DMRelationshipProperty")
            {
                var relationshipProperty = (DMRelationshipProperty)toBO;
                var fromDMProperty = (DMProperty) fromRelatedBO;
                if(relationshipProperty.Relationship == null || relationshipProperty.Relationship.OwnerClass == null)
                {
                    return base.CreateMergedBusinessObject(toSingleRelationship, fromRelatedBO, toBO);
                }
                var dmProperty = relationshipProperty.Relationship.OwnerClass.GetDMProperty(fromDMProperty.PropertyName);
                if (dmProperty == null)
                {
                    return base.CreateMergedBusinessObject(toSingleRelationship, fromRelatedBO, toBO);
                }
                return (DMProperty) dmProperty;
            }
            return base.CreateMergedBusinessObject(toSingleRelationship, fromRelatedBO, toBO);
        }

        protected override IMergableBo CreateMergedBusinessObject(IBusinessObjectCollection toBoCol, IMergableBo fromBO)
        {
            //This is a strange relationship since the DMProperty is owned by the DMClass and the 
            // relationship has to find the exact DMProperty that the DMClass has so as to work.
            // Another approach which might be more elegant would be to set the PropName and related prop name and
            // not the actual property. We could then run the post load processer against this to sort the actual
            // property out. This would however require some fairly significant changes to the
            // BusinessObjectMerger so for now I am living with this Hack_
            if (fromBO.ClassDef.ClassName == "DMRelationship")
            {
                DMRelationship fromRelationship = (DMRelationship) fromBO;
                var toRelationship = new DMRelationship(null);
                toRelationship.ReverseRelationshipName = fromRelationship.ReverseRelationshipName;
                toRelationship.RelatedAssemblyName = fromRelationship.RelatedAssemblyName;
                toRelationship.RelatedClassName = fromRelationship.RelatedClassName;
                IMergableBo toBO = toRelationship;
                 MergeBusinessObjects(fromBO, toBO);
                 return toBO;
            }
            if (fromBO.ClassDef.ClassName == "DMRelationshipProperty")
            {
                DMRelationshipProperty fromRelProp = (DMRelationshipProperty)fromBO;
                var toRelProp = new DMRelationshipProperty(null);
                toRelProp.RelatedPropertyName = fromRelProp.RelatedPropertyName;
                toRelProp.OwnerPropertyName = fromRelProp.OwnerPropertyName;
                IMergableBo toBO = toRelProp;

                MergeBusinessObjects(fromBO, toBO);
                return toBO;
            }
            return base.CreateMergedBusinessObject(toBoCol, fromBO);
        }
    }
}